#@DESC:
#@TODO:

class MapAdditionalInfo:
  def __init__(self,game_map):
    self.game_map = game_map
    self.squads = []
    
    
  def rotateSquads(self,x,y):
    if len(self.getTile(x,y).squads)>1:
      first = self.getTile(x,y).squads[0]
      self.getTile(x,y).squads = self.getTile(x,y).squads[1:]
      self.getTile(x,y).squads.append(first)
  
  def addVantagePoints(self,x,y,vantage_data):
    #self.getTile(x,y).vantage_data =
    self.vantage_points.append([x,y])
      
  def clearVantagePoints(self):
    pass
    
  def addSquadLink(self,x,y,squad):
    self.getTile(x,y).squads.append(squad)
    if len(self.getTile(x,y).squads)==1:
      self.tiles_with_squads.append((x,y))
    
  def removeSquadLink(self,x,y,squad):
    self.getTile(x,y).squads.remove(squad)
    if len(self.getTile(x,y).squads)==0:
      self.tiles_with_squads.remove((x,y))


class GameLogic:
  def __init__(self,name,code_map):
    random.seed(100)
    self.commanders = []
    self.playable_commander = None
    self.database = Database()
    self.map = Map(code_map)
    self.time_zero = 0
    self.time = 0
    self.time_step = 900
    self.preview_step = 60
    self.sides = []
    self.squads = []
    self.layers = []
    self.controls = []
    self.vantage_points = []
    self.states = ['zero_phase','squad_movement','strategy_choice']
    self.active_state = []
    self.selected_squad = None
    self.views =['squad_control','squad_info']
    self.active_view = 'squad_control'
    self.pt = {}
        
    self.time_zero = time.strptime("30 Nov 10", "%d %b %y")
    
  #calculation logic funcs
  def unload(self,squad):
    if squad.motorized_state == "loaded":
      sq2 = self.splitSquad(squad,[squad.units[0]],squad.units[1:])
      sq2.completeLastOrder()
      sq2.icon = "infantry"
      squad.motorized_state = "unloaded"
      squad.completeLastOrder()
      
  def load(self,squad):
    if squad.motorized_state == "unloaded":
      self.mergeSquads(squad,squad.bound_squad)
      squad.motorized_state = "loaded"
      squad.completeLastOrder()
    
  def calculateMorale(self,squad):
    pass
  def calculateSpeed(self,squad,tile_info):
    speed = squad.speed * se(squad.chassis,map.getTile(x,y).terrain) * squad.fatigue
    return speed

  def calculaterReactions(self):
    pass
    

      
  #squad orders functions
  def isVisible(self,unit):
    pass
  def calculateFieldOfView(self):
    pass
  def attack(self,squad):
    if not self.enemyAtTile(squad.orders[0].target[0][0],squad.orders[0].target[0][1]):
       squad.completeLastOrder()
    else:
      self.calculateAttack(squad)
      #self.destroySquad(self.map.getTile(squad.orders[0].target[0][0],squad.orders[0].target[0][1]).squads[0])
      
  def calculateAttack(self,squad):
    firepower = [0.0,0.0]
    AT_fire = [0.0,0.0]
    AA_fire = [0.0,0.0]
    sniping_fire = [0.0,0.0]
    for unit in squad.units:
      if squad.motorized_state == "loaded" and not self.database.getUnitInfo(unit.name)['type'] == 'transport':
        continue
      
      info = self.database.getWeaponInfo(self.database.getUnitInfo(unit.name)['main_w'])
      
      if info is None:
        pass
      elif info['damage_type'] == 'automatic_fire':
        firepower = sumFirepower(firepower,[float(info['firepower']),float(info['precision'])])
      elif info['damage_type'] == 'shaped_charge' :
        firepower = sumFirepower(firepower,[float(info['firepower']),float(info['precision'])])
        AT_fire = [AT_fire[0]+float(info['firepower']),AT_fire[1]+(1.0 - AT_fire[1])*float(info['precision'])]
      
    
    vantagePoint = squad.orders[0].target[0][0],squad.orders[0].target[0][1]
    if vantagePoint not in self.vantage_points:
      self.vantage_points[vantagePoint] = [firepower,AT_fire]
    else:
      self.vantage_points[vantagePoint][0] = sumFirepower(self.vantage_points[vantagePoint][0],firepower)
      self.vantage_points[vantagePoint][1] = sumFirepower(self.vantage_points[vantagePoint][1],AT_fire)
     
  
  def calculateDefense(self,squad):
    squad.infantry_defense = 1.0
    if squad.motorized_state == "loaded":
      squad.infantry_defense += 2.0
    squad.armor_defense = 1.0
    
    
  def seekAndDestroy(self,squad):
    pass
  
  def destroySquad(self,squad):
    if squad in self.squads:
      self.map.removeSquadLink(squad.pos[0],squad.pos[1],squad)
      if squad == self.selected_squad:
        self.selected_squad = None
      self.squads.remove(squad)
    
  def autoReturnFire(self,squad):
    pass
    
  def redeploy(self,squad,complete = True):
    
    if squad.order_status == 'starting':
      squad.order_status = 'proceeding'
      self.setPath(squad,squad.orders[0].target[0])
      
    if squad.subposition >= 100:
      self.map.removeSquadLink(squad.pos[0],squad.pos[1],squad)
      squad.pos = squad.path[0]
      self.map.addSquadLink(squad.pos[0],squad.pos[1],squad)
      squad.subposition = 0
      if(len(squad.path)>1):
        squad.path = squad.path[1:]
      else:
        squad.path = []
        if complete:
          squad.completeLastOrder()
    else:
      if len(squad.path) > 0:
        if len(self.map.getTile(squad.path[0][0],squad.path[0][1]).squads)>3:
          if len(squad.path)<2:
            if complete:
              squad.completeLastOrder()
          else:
            self.setPath(squad,squad.path[-1])
        else:
          squad.subposition = squad.subposition + int(self.database.units['btr80']['max_speed'])

  def mergeSquads(self,squad1,squad2):
    for unit in squad2.units:
      squad1.units.append(unit)
    
    self.map.removeSquadLink(squad2.pos[0],squad2.pos[1],squad2)
    self.squads.remove(squad2)
    
    
  def splitSquad(self,squad,units1,units2):
      #self.addNamedSquad(self.playable_commander.name,'mechanized',squad.pos)
      self.squads.append(Squad(squad.name,squad.name,"infantry"))
      for unit in units2:
        squad.units.remove(unit)
      
      self.squads[-1].icon = 'infantry'
      self.squads[-1].units = []
      self.squads[-1].pos = squad.pos
      self.squads[-1].commander = self.playable_commander.name
      
      self.map.addSquadLink(self.squads[-1].pos[0],self.squads[-1].pos[1],self.squads[-1])
      
      for unit in units2:
        self.squads[-1].units.append(unit)
      squad.bound_squad = self.squads[-1]
      self.squads[-1].bound_squad = squad
      return self.squads[-1]
      
  def addNamedSquad(self,commander,name,pos):
      self.squads.append(self.database.getSquad(name))
      self.squads[-1].pos = pos
      self.squads[-1].commander = commander
      self.map.addSquadLink(self.squads[-1].pos[0],self.squads[-1].pos[1],self.squads[-1])
      

  def recon(self,area,squad):
    self.awarness = 3
  def assault(self,area):
    self.awarness = 1
    self.attack_bonus = 2
    self.support_usage = True
    


  def update(self,squad):
    if squad.order_status == 'proceeding' or squad.order_status == 'starting':
      if squad.morale > 4:
        if squad.orders[0].name == 'redeploy':
          self.redeploy(squad)
        elif squad.orders[0].name == 'attack':
          if (abs(squad.pos[0] - squad.orders[0].target[0][0]))>1 or abs(squad.pos[1] - squad.orders[0].target[0][1])>1:
            self.redeploy(squad)
          else:
            self.attack(squad)
        elif squad.orders[0].name == 'unload':
          self.unload(squad)
        elif squad.orders[0].name == 'load':
          if squad.pos != (squad.orders[0].target[0][0],squad.orders[0].target[0][1]):
            self.redeploy(squad,complete = False)
          else:
            self.load(squad)
          
        elif squad.orders[0].name == 'assault':
          pass
        elif squad.orders[0].name == 'suppress':
          pass
        elif squad.orders[0].name == 'patrol':
          pass
      else:
        if squad.morale == 0:
          pass
          
    self.calculateDefense(squad)

  
